package com.apexsoft.front.common.plugins.filter.impl;

import java.io.PrintWriter;
import java.util.List;
import java.util.regex.Pattern;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.apexsoft.front.common.utils.AddressUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.alibaba.fastjson.JSONObject;
import com.apexsoft.front.common.plugins.filter.IFilter;
import com.apexsoft.front.common.plugins.filter.annotation.AFilter;
import com.apexsoft.front.common.utils.JsonResult;
import com.apexsoft.front.common.utils.session.UserSessionNoRedis;

@AFilter(name="Common Filter")
public class CommonFilter implements IFilter {
	
	private static final Logger log = LogManager.getRootLogger();

	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object obj) throws Exception {
		// session过滤
		String requestURI = request.getRequestURI();
		String contextPath = request.getServletContext().getContextPath();
		String requestPath = requestURI.substring(contextPath.length());
		String sessionId = request.getRequestedSessionId();
		requestPath = formatRequestURI(requestPath);
		log.debug("\n当前请求action:"+requestURI+";当前的SessionId："+sessionId);
		//走白名单
		if (!this.needSessionFilter(request, requestPath)) {
			return true;
		}else{//非白名单 走回话控制机制
			Object object = null;
			object = UserSessionNoRedis.getSessionObj(request, UserSessionNoRedis.CONSOLE_SESSION);
			//请求超时
			if(object==null){
				this.timeout(request, response, requestPath);
				return false;
			}else{
				return true;
			}
		}
	}
	
	/**
	 * 超时处理
	 * 
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	private void timeout(HttpServletRequest request, HttpServletResponse response, String requestPath) throws Exception {
		String requestType = request.getHeader("X-Requested-With"); // XMLHttpRequest
		if ("XMLHttpRequest".equals(requestType)) {// 异步请求
			// /wskh/flow/media/upload影像表单提交异步请求 特殊处理
			PrintWriter out = null;
			response.setContentType("text/html;charset=UTF-8");
			try {
				out = response.getWriter();
				response.setStatus(911);// 超时标记
				JSONObject result = new JsonResult(false, "会话已过期,请重新登录").getResult();
				result.put("timeout", true);
				out.println(result.toString());
			} catch (Exception e) {
				log.error(e.getMessage());
			} finally {
				out.close();
			}
		} else {// 直接请求
			String requestURI = request.getRequestURI();
			if(requestURI.contains("mobile")){//移动端Action 超时后进入移动端超时界面
				request.getRequestDispatcher("/mobile/timeout").forward(request, response);
			}else{
				request.getRequestDispatcher("/timeout").forward(request, response);
			}
		}
	}
	
	/**
	 * 根据配置返回请求是否需要判断session过期
	 * 
	 * @param path
	 * @param method
	 * @return
	 */
	private boolean needSessionFilter(HttpServletRequest request, String path) {
		ServletContext context = request.getServletContext();
		List<String> whiteList = (List<String>) context.getAttribute("whiteList");
		for (String item : whiteList) {
			if (Pattern.matches(item, path))
				return false;
		}
		return true;
	}
	
	/**
	 * 去除访问地址串中多余的的斜杠，防止绕过过滤器
	 * 
	 * @param uri
	 * @return
	 */
	private String formatRequestURI(String uri) {
		String[] s = uri.split("/");
		StringBuffer result = new StringBuffer();
		for (String c : s) {
			if (!"".equals(c.trim()))
				result.append("/").append(c);
		}
		return result.toString();
	}

}
